package com.wang.common.utils;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 公共工具类
 */
@Slf4j
public class Utils {

    /**
     * 返回缩进位数
     *
     * @param indent 缩进个数
     * @return 缩进位数
     */
    public static String indentN(Integer indent, String INDENT) {
        indent = Math.max(indent, 0);
        return String.join("", Collections.nCopies(indent, INDENT));
    }

    public static String indentN(Integer indent) {
        return indentN(indent, "  ");
    }

    /**
     * 校验Line
     *
     * @param line 行
     * @return str
     */
    public static String checkLine(String line, String SYMBOL) {
        // 去除行中所有的换行、回车、空格符号
        String s = line.replaceAll("\n|\r|\\s", "");
        // 如果为空，则转到下一行 || 注释 || 不存在
        if (s.length() == 0 || !line.contains(SYMBOL)) {
            return null;
        }
        // 行内如果出现 \u0009，则删除它
        if (line.contains("\u0009")) {
            line = line.replace("\u0009", "");
        }
        // 行内如果出现""，则在其之前添加\转义
        if (line.contains("\"")) {
            line = line.replace("\"", "\\\"");
        }
        return line;
    }

    public static String checkLine(String line) {
        return checkLine(line, "=");
    }

    /**
     * unicode transfer to Chinese
     * 将unicode码转换为中文
     *
     * @param suffix unicode字符串
     * @return Chinese字符串
     */
    public static String unicodeToCN(String suffix) {
        // unicode 转 汉字
        Pattern compile = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = compile.matcher(suffix);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            suffix = suffix.replace(matcher.group(1), ch + "");
        }
        return suffix;
    }

    /**
     * 斜杠替换
     *
     * @param str 可能含有斜杠的字符串
     * @return 斜杠替换后的字符串
     * @since 2022.7.26
     */
    public static String replaceSlash(String str) {

        char[] chars = str.toCharArray();
        // 旧的char
        char oldC = 'c';
        StringBuilder newStr = new StringBuilder();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (c == '\\'
                    && (oldC != '\\'
                    && (i != chars.length - 1 && chars[i + 1] != '\\' && chars[i + 1] != '"'))) {
                newStr.append("\\");
            }
            newStr.append(c);
            oldC = c;
        }
        return newStr.toString();
    }

    /**
     * 日期格式化转字符串
     */
    public static String convertDateToString(Date date, String pattern) {
        if (null == date) {
            return null;
        }
        String str = "";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        try {
            str = simpleDateFormat.format(date);
        } catch (Exception e) {
            return null;
        }
        return str;
    }

    /**
     * 当前日期格式化转字符串
     * 固定格式：yyyyMMdd HH:mm:ss
     */
    public static String convertDateToString() {
        return convertDateToString(new Date(), "yyyyMMddHHmmss");
    }

    /**
     * 字符串格式化转日期
     */
    public static Date covertStringToDate(String str, String pattern) {
        if ("".equals(str)) {
            return null;
        }
        Date date = null;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        try {
            date = simpleDateFormat.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        return date;
    }

    /**
     * 生成随机ID
     */
    public static String genRanNo() {
        String date = convertDateToString(new Date(), "yyyyMMdd");
        String nanoTime = String.valueOf(System.nanoTime());
        nanoTime = nanoTime.substring(nanoTime.length() - 10);
        return "230111" + date + nanoTime + (long) ((Math.random() * 9.0D + 1.0D) * 1.0E7D);
    }

    /**
     * 生成随机用户ID
     */
    public static String genUserid() {
        String date = convertDateToString(new Date(), "yyyyMMdd");
        String nanoTime = String.valueOf(System.nanoTime());
        nanoTime = nanoTime.substring(nanoTime.length() - 10);
        return "230111" + date + nanoTime + (long) ((Math.random() * 9.0D + 1.0D) * 1.0E3D);
    }

    /**
     * 密码 md5 加密
     */
    public static String encodePassword(String password) {
        return DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 判断是否为空
     */
    public static Boolean isEmpty(CharSequence str) {
        return StringUtils.isEmpty(str);
    }

    public static Boolean isEmpty(Object obj) {
        return ObjectUtils.isEmpty(obj);
    }

    /**
     * 判断是否不为空
     */
    public static Boolean isNotEmpty(CharSequence str) {
        return !isEmpty(str);
    }

    public static Boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    /**
     * 账号特殊字符校验
     */
    public static Boolean hasSpecialChar(String str) {
        String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Matcher matcher = Pattern.compile(validPattern).matcher(str);
        return matcher.find();
    }

    /**
     * isAnyBlank
     */
    public static Boolean isAnyBlank(CharSequence... css) {
        return StringUtils.isAnyBlank(css);
    }

    /**
     * isAllBlank
     */
    public static Boolean isAllBlank(CharSequence... css) {
        return StringUtils.isAllBlank(css);
    }

    /**
     * 实体类转xml格式
     */
    public static void XMLParse(Object entity, Class<?> clazz) {
        try {
            JAXBContext context = JAXBContext.newInstance(clazz);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            MarshallerListener marshallerListener = new MarshallerListener();
            marshaller.setListener(marshallerListener);
            StringWriter writer = new StringWriter();
            marshaller.marshal(entity, writer);
            log.info("\n" + writer);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    /**
     * json 对象转json字符串
     */
    public static String objToJsonString(Object obj) {
        return JSON.toJSONString(obj);
    }

    /**
     * json json字符串转对象
     */
    public static Object jsonStringToObj(String str, Class<?> clazz) {
        return JSON.parseObject(str, clazz);
    }

    /**
     * 表ID自动增加，并格式化 <br>
     * 0开头补全
     */
    public static String formatId(String id, Integer length) {
        int nid = Integer.parseInt(id) + 1;
        int len = String.valueOf(nid).length();
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < (length - len); i++) {
            s.append("0");
        }
        return s + String.valueOf(nid);
    }
}
